package com.yxf.variousshapes3d.programs;

import android.content.Context;


import com.yxf.variousshapes3d.CommonUtils;

import static android.opengl.GLES20.glUseProgram;

public abstract class Program {

    protected int program;

    private int vertexResourceId, fragmentResourceId;

    private ShaderCallback shaderCallback;

    public Program() {

    }

    public void onSurfaceCreated(Context context) {
        ShaderCallback callback = getShaderCallback();
        this.vertexResourceId = callback.getVertexResourceId();
        this.fragmentResourceId = callback.getFragmentResourceId();
        shaderCallback = callback;
        if (callback == null) {
            throw new RuntimeException("the shader callback of program can not is null , program : " + getClass().getName());
        }
        String vertexShaderSource = CommonUtils.readTextFromResource(context, vertexResourceId);
        String fragmentShaderSource = CommonUtils.readTextFromResource(context, fragmentResourceId);
        int vertexShader = CommonUtils.compileVertexShader(vertexShaderSource);
        int fragmentShader = CommonUtils.compileFragmentShader(fragmentShaderSource);
        program = CommonUtils.linkProgram(vertexShader, fragmentShader);
        shaderCallback.initialize(program);
    }

    public void onSurfaceChanged(int width, int height) {

    }


    protected void useProgram() {
        glUseProgram(program);
    }

    public void onDrawFrame() {
        useProgram();
        shaderCallback.prepareDraw(program);
    }

    public abstract ShaderCallback getShaderCallback();

    interface ShaderCallback {

        int getVertexResourceId();

        int getFragmentResourceId();

        void initialize(int program);

        void prepareDraw(int program);
    }
}
